package com.talkweb.baselibrary.adapter;

import ohos.agp.components.BaseItemProvider;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.app.Context;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * 封装ListContainer的适配器
 * @param <T>   javaBean
 * @param <V>   BaseViewHolder
 */
public abstract class BaseItemAdapter<T, V extends BaseViewHolder> extends BaseItemProvider {

    private Context mContext;
    private List<T> mList;
    private int mResourceId;

    private List<T> getData() {
        return mList;
    }

    public void setNewData(List<T> list) {
        mList = list == null ? new ArrayList<>() : list;
        notifyDataChanged();
    }

    public BaseItemAdapter(int resourceId, List<T> list) {
        mResourceId = resourceId;
        mList = list == null ? new ArrayList<T>() : list;
    }

    public BaseItemAdapter(int resourceId) {
        this(resourceId, null);
    }

    @Override
    public int getCount() {
        return mList == null ? 0 : mList.size();
    }

    @Override
    public Object getItem(int position) {
        if (mList != null && position >= 0 && position < mList.size()) {
            return mList.get(position);
        }
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public Component getComponent(int position, Component component, ComponentContainer componentContainer) {
        final Component cpt;
        V viewHolder;
        if (component == null) {
            if (mContext == null) {
                mContext = componentContainer.getContext();
            }
            cpt = LayoutScatter.getInstance(mContext).parse(mResourceId, null, false);
            viewHolder = createViewHolder(cpt);
            cpt.setTag(viewHolder);
        } else {
            cpt = component;
            viewHolder = (V) cpt.getTag();
        }

        T item = mList.get(position);
        convert(position, item, viewHolder);

        return cpt;
    }

    private V createViewHolder(Component itemView) {
        Class temp = getClass();
        Class z = null;
        while (z == null && null != temp) {
            z = getInstancedGenericClass(temp);
            temp = temp.getSuperclass();
        }
        V v = createGenericKInstance(z, itemView);
        return v != null ? v : (V) new BaseViewHolder(itemView);
    }

    private Class getInstancedGenericClass(Class z) {
        Type type = z.getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            Type[] types = ((ParameterizedType) type).getActualTypeArguments();
            for (Type temp : types) {
                if (temp instanceof Class) {
                    Class tempClass = (Class) temp;
                    if (BaseViewHolder.class.isAssignableFrom(tempClass)) {
                        return tempClass;
                    }
                }
            }
        }
        return null;
    }

    private V createGenericKInstance(Class z, Component view) {
        try {
            Constructor constructor;
            if (z.isMemberClass() && !Modifier.isStatic(z.getModifiers())) {
                constructor = z.getDeclaredConstructor(getClass(), Component.class);
                constructor.setAccessible(true);
                return (V) constructor.newInstance(this, view);
            } else {
                constructor = z.getDeclaredConstructor(Component.class);
                constructor.setAccessible(true);
                return (V) constructor.newInstance(view);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public abstract void convert(int position, T item, V viewHolder);
}
